Skip to content

Initial OSS logging adapter for http#2008

Open
mattdholloway wants to merge 7 commits intomainfrom
add-logging-stack-v2
Open

Initial OSS logging adapter for http#2008
mattdholloway wants to merge 7 commits intomainfrom
add-logging-stack-v2

Conversation

@mattdholloway
Copy link
Contributor

Summary

Why

Fixes #

What changed

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR

Note: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Not needed
  • Updated (README / docs / examples)

@mattdholloway mattdholloway marked this pull request as ready for review February 18, 2026 14:29
@mattdholloway mattdholloway requested a review from a team as a code owner February 18, 2026 14:29
Copilot AI review requested due to automatic review settings February 18, 2026 14:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new pkg/observability layer (logger + metrics adapters) and wires it into the GitHub tool dependency construction for both HTTP and stdio server paths.

Changes:

  • Added pkg/observability with backend-agnostic log.Logger / metrics.Metrics interfaces plus noop + slog adapters and tests.
  • Extended pkg/github dependency plumbing to provide Logger() / Metrics() on ToolDependencies, and to accept a *slog.Logger in NewBaseDeps / NewRequestDeps.
  • Threaded the HTTP server’s slog.Logger into request deps and the stdio server’s cfg.Logger into base deps.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/observability/observability.go Defines Exporters interface and basic implementation.
pkg/observability/observability_test.go Unit tests for NewExporters.
pkg/observability/log/logger.go Adds backend-agnostic logger interface.
pkg/observability/log/level.go Adds log level type/constants.
pkg/observability/log/field.go Adds structured field type + helpers.
pkg/observability/log/noop_adapter.go No-op logger implementation.
pkg/observability/log/slog_adapter.go slog-backed logger adapter.
pkg/observability/log/slog_adapter_test.go Tests for SlogLogger.
pkg/observability/metrics/metrics.go Adds backend-agnostic metrics interface.
pkg/observability/metrics/noop_adapter.go No-op metrics implementation.
pkg/observability/metrics/noop_adapter_test.go Tests for NoopMetrics.
pkg/observability/metrics/slog_adapter.go slog-backed metrics adapter.
pkg/observability/metrics/slog_adapter_test.go Tests for SlogMetrics.
pkg/github/dependencies.go Adds observability to ToolDependencies; updates constructors to accept *slog.Logger.
pkg/github/dependencies_test.go Updates constructor calls for new signature.
pkg/github/feature_flags_test.go Updates constructor calls for new signature.
pkg/github/dynamic_tools_test.go Updates constructor calls for new signature.
pkg/github/server_test.go Updates test deps to provide Logger/Metrics.
pkg/http/server.go Passes HTTP server logger into NewRequestDeps.
internal/ghmcp/server.go Passes cfg.Logger into NewBaseDeps.
Comments suppressed due to low confidence (3)

pkg/github/dependencies.go:145

  • NewBaseDeps’ signature now requires a *slog.Logger, which is a breaking change for downstream callers. Consider preserving the existing constructor (old signature) and adding a new constructor/option for observability (e.g., NewBaseDepsWithLogger or functional options) to avoid forcing updates for all consumers.
	flags FeatureFlags,
	contentWindowSize int,
	featureChecker inventory.FeatureFlagChecker,
	logger *slog.Logger,
) *BaseDeps {

pkg/github/dependencies.go:296

  • NewRequestDeps’ signature now requires a *slog.Logger, which is a breaking change for downstream callers. Consider keeping the old signature and adding an alternate constructor/option for supplying a logger to avoid a hard API break.
	t translations.TranslationHelperFunc,
	contentWindowSize int,
	featureChecker inventory.FeatureFlagChecker,
	logger *slog.Logger,
) *RequestDeps {

pkg/github/server_test.go:76

  • stubDeps.Metrics ignores the provided ctx and calls the exporter with context.Background(), which can hide context-dependent metrics behavior in tests. Pass the incoming ctx through to s.obsv.Metrics(ctx) for consistency.
func (s stubDeps) Metrics(_ context.Context) mcpMetrics.Metrics {
	if s.obsv != nil {
		return s.obsv.Metrics(context.Background())
	}
	return mcpMetrics.NewNoopMetrics()

Comment on lines +102 to +106
// Logger returns the logger
Logger(ctx context.Context) obsvLog.Logger

// Metrics returns the metrics client
Metrics(ctx context.Context) obsvMetrics.Metrics
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding Logger/Metrics to ToolDependencies is a breaking interface change for any external dependency provider (e.g., remote server or third-party users). If backward compatibility is required, consider introducing a separate optional interface (and type-assert at call sites) or a new ToolDependenciesV2, rather than extending the existing interface directly.

This issue also appears in the following locations of the same file:

  • line 141
  • line 292

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +150
var obsv observability.Exporters
if logger != nil {
obsv = observability.NewExporters(obsvLog.NewSlogLogger(logger, obsvLog.InfoLevel), obsvMetrics.NewNoopMetrics())
} else {
obsv = observability.NewExporters(obsvLog.NewNoopLogger(), obsvMetrics.NewNoopMetrics())
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default observability/exporters initialization logic is duplicated in NewBaseDeps and NewRequestDeps. Consider extracting a small helper (e.g., newDefaultExporters(logger *slog.Logger) observability.Exporters) to keep behavior consistent and avoid future drift.

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +74
func (s stubDeps) Logger(_ context.Context) mcpLog.Logger {
if s.obsv != nil {
return s.obsv.Logger(context.Background())
}
return mcpLog.NewNoopLogger()
}
func (s stubDeps) Metrics(_ context.Context) mcpMetrics.Metrics {
if s.obsv != nil {
return s.obsv.Metrics(context.Background())
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stubDeps.Logger ignores the provided ctx and calls the exporter with context.Background(), which can mask context-dependent logging behavior in tests. Pass the incoming ctx through to s.obsv.Logger(ctx) to better reflect real execution.

This issue also appears on line 72 of the same file.

Suggested change
func (s stubDeps) Logger(_ context.Context) mcpLog.Logger {
if s.obsv != nil {
return s.obsv.Logger(context.Background())
}
return mcpLog.NewNoopLogger()
}
func (s stubDeps) Metrics(_ context.Context) mcpMetrics.Metrics {
if s.obsv != nil {
return s.obsv.Metrics(context.Background())
func (s stubDeps) Logger(ctx context.Context) mcpLog.Logger {
if s.obsv != nil {
return s.obsv.Logger(ctx)
}
return mcpLog.NewNoopLogger()
}
func (s stubDeps) Metrics(ctx context.Context) mcpMetrics.Metrics {
if s.obsv != nil {
return s.obsv.Metrics(ctx)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments